﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;

namespace ABFramework
{
    /// <summary>
    /// 构建Assetbundle资源委托
    /// </summary>
    /// <param name="bt">构建平台</param>
    /// <param name="platform_desc">平台描述</param>
    public delegate void DelegateDoBuildFunc(BuildTarget bt, string platform_desc);

    /// <summary>
    /// 发布项目类
    /// </summary>
    public class DeployAssetsBundle
    {
        /// <summary>
        /// 发布Android的热更资源
        /// </summary>
        [MenuItem("Tools/链式发布资源(正式)/To Android")]
        public static void DeployAndroidPlatformAssetsBundle()
        {
            CheckCurrentPlatformThenBuild(BuildTarget.Android, DoDeployOperate);
        }

        /// <summary>
        /// 发布Windows的热更资源
        /// </summary>
        [MenuItem("Tools/链式发布资源(正式)/To Windows")]
        public static void DeployWindowsAssetsBundle()
        {
            CheckCurrentPlatformThenBuild(BuildTarget.StandaloneWindows64, DoDeployOperate);
        }

        /// <summary>
        /// 发布iOS的热更资源
        /// </summary>
        [MenuItem("Tools/链式发布资源(正式)/To iOS")]
        public static void DeployiOSAssetsBundle()
        {
            CheckCurrentPlatformThenBuild(BuildTarget.iOS, DoDeployOperate);
        }

        /// <summary>
        /// 发布当前平台的热更资源
        /// </summary>
        [MenuItem("Tools/链式发布资源(正式)/发布到当前平台")]
        public static void DeployCurrentPlatformAssetsBundle()
        {
            BuildTarget platform = EditorUserBuildSettings.activeBuildTarget;

            CheckCurrentPlatformThenBuild(platform, DoDeployOperate);
        }

        /// <summary>
        /// 执行项目发布操作
        /// </summary>
        /// <param name="bt">目标平台</param>
        /// <param name="platform_desc">平台描述</param>
        private static void DoDeployOperate(BuildTarget bt, string platform_desc)
        {
            Debug.Log("开始-" + platform_desc + "-项目发布操作!!! " + DateTime.Now);

            //开始时间
            DateTime start_time = DateTime.Now;
            //1.设置Assetbundle标签
            SetAssetBundleLabel.SetABleLabels();

            //2.构建ab资源
            BuildAssetBundles.DoBuildAssetBundle(bt, platform_desc);

            //3.复制lua代码
            CopyLuaScripts.DoCopyLuaScripts();

            //4.创建校验文件
            CreateVerifyFile.CreateTheVerifyFile();

            //5.复制需要热更的文件到发布目录
            CopyHotupdteFileToDeployDirectory();

            //结束时间
            DateTime end_time = DateTime.Now;
            var used_time = Math.Round(((end_time.Subtract(start_time).TotalMilliseconds) / 1000.0), 3);
            Debug.Log("完成-" + platform_desc + "-项目发布操作!!! " + DateTime.Now + " Use Time ：" + used_time + " s");

            //刷新资源列表
            AssetDatabase.Refresh();

            OperateDirectory.OpenLastDeployDirectory();
        }


        /// <summary>
        /// 复制当前平台需要热更的文件到发布目录
        /// 复制之前需要检测是否有版本配置文件，无配置文件则取消复制发布
        /// 将发布的目标目录上传至服务器实现热更
        /// </summary>
        [MenuItem("Tools/资源操作(Step)/5.复制到热更目录(指定版本)")]
        public static void CopyHotupdteFileToDeployDirectory()
        {
            //检测热更资源版本配置文件是否存在
            string config_file = Application.dataPath + "/../" + PathTools.BUILD_AB_OUT_PATH + "/" + PathTools.UPDATE_VERSION_CONFIG;
            if (!File.Exists(config_file))
            {
                if (EditorUtility.DisplayDialog("没找到配置文件", "没找到热更资源配置文件,复制到发布目录之前请先创建版本配置文件!\n\n点击确定打开热更资源配置窗口", "确定", "关闭"))
                {
                    DeployByViewport.CloseWindow();
                    DeployByViewport.ShowWindow();
                }
                Debug.LogError("ERROR：复制热更资源到指定版本目录（Step 5）失败，没有对应的版本配置文件!!!配置版本配置文件后直接执行【Step 5】即可完成发布!!!");
                return;
            }

            //热更资源版本配置文件数据对象-取到版本号
            VersionObject vobj = JsonUtility.FromJson<VersionObject>(File.ReadAllText(config_file));

            //当前平台所有需要热更资源的根目录地址
            string hotupdate_root_path = Application.streamingAssetsPath + "/" + BuildAssetBundles.GetCurrentlyPlatform();
            //需要复制到的目标地址+版本号
            string hotupdate_out_path = Application.dataPath + "/../" + PathTools.BUILD_AB_OUT_PATH + "/" + vobj.version;
            //该版本目录下对应的平台的根目录
            string hu_platform_path = hotupdate_out_path + "/" + BuildAssetBundles.GetCurrentlyPlatform();

            string version_name = new FileInfo(hotupdate_out_path).Name;

            //检测版本目录打头字符串是否为规定的
            if (!version_name.StartsWith("Version-"))
            {
                Debug.LogError("请确保资源版本目录以 “Version-” 开头!!!当然,其实不以这个开头也没事...");
            }

            if (Directory.Exists(hu_platform_path))
            {
                Directory.Delete(hu_platform_path, true);
            }
            Directory.CreateDirectory(hu_platform_path);

            //检测是否存在Lua脚本目录
            if (!Directory.Exists(hotupdate_root_path))
            {
                Debug.LogError("Error!!! 将被复制的目录不存在!!!请检查“hotupdate_root_path”热更资源是否发布完成!!!");
                return;
            }
            //递归复制
            string head_path = Application.streamingAssetsPath;
            CommonTools.CopyAssetsToDestionDirRecursion(hotupdate_root_path, head_path, hotupdate_out_path);

            //Debug.Log("HotUpdate：" + version_name);
            Debug.Log("Step 5.复制所有热更文件到指定版本“" + version_name + "”目录完成!!!");
        }


        /// <summary>
        /// 检测当前编译平台，不是这则选择切换 然后打包到目标平台
        /// </summary>
        /// <param name="platform">目标平台</param>
        /// <returns></returns>
        public static void CheckCurrentPlatformThenBuild(BuildTarget platform, DelegateDoBuildFunc _delegateDoBuildFunc)
        {
            //目标平台组
            BuildTargetGroup group = BuildTargetGroup.Unknown;
            //当前平台描述文字
            string current_platform_desc = string.Empty;

            switch (platform)
            {
                case BuildTarget.StandaloneWindows:
                case BuildTarget.StandaloneWindows64:
                    group = BuildTargetGroup.Standalone;
                    current_platform_desc = PathTools.DESC_WINDOWS;
                    break;
                case BuildTarget.iOS:
                    group = BuildTargetGroup.iOS;
                    current_platform_desc = PathTools.DESC_IOS;
                    break;
                case BuildTarget.Android:
                    group = BuildTargetGroup.Android;
                    current_platform_desc = PathTools.DESC_ANDROID;
                    break;
            }
            //检测打包平台是否为当前编译平台
            if (platform != EditorUserBuildSettings.activeBuildTarget)
            {
                string desc2 = "平台异常提示！";
                string desc3 = "当前编译环境不为【" + current_platform_desc + "】平台，是否切换到" + current_platform_desc + "平台!\n\n切换后将继续构建资源！";
                string desc4 = "切换到" + current_platform_desc + "平台";
                string desc5 = "取消构建！";
                string desc6 = "切换到【" + current_platform_desc + "】平台，继续构建AssetBundle！！！";

                //询问是否切换平台
                bool is_change = EditorUtility.DisplayDialog(desc2, desc3, desc4, desc5);

                if (is_change)
                {
                    EditorUserBuildSettings.activeBuildTargetChanged = delegate ()
                    {
                        Debug.Log(desc6);
                        _delegateDoBuildFunc.Invoke(platform, current_platform_desc);
                    };
                    EditorUserBuildSettings.SwitchActiveBuildTarget(group, platform);
                }
                else
                {
                    Debug.LogWarning("取消构建AssetBundle！！！");
                }
            }
            else
            {
                _delegateDoBuildFunc.Invoke(platform, current_platform_desc);
            }
        }

    }
}
